home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 3578 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.2 KB  |  121 lines

  1. Newsgroups: comp.lang.c
  2. Path: news.sprintlink.net!eskimo!scs
  3. From: scs@eskimo.com (Steve Summit)
  4. Subject: Re: looping & sscanf
  5. X-Nntp-Posting-Host: eskimo.com
  6. Message-ID: <DLyz1B.DvK@eskimo.com>
  7. Sender: news@eskimo.com (News User Id)
  8. Organization: schmorganization
  9. References: <DLtqMw.8Ao@emr1.emr.ca>
  10. Date: Tue, 30 Jan 1996 01:05:34 GMT
  11.  
  12. In article <DLtqMw.8Ao@emr1.emr.ca>, jagrant@emr1.emr.ca (John Grant) writes:
  13. > In FORTRAN, I can read a set of numbers from a character string with an
  14. > 'internal read'...
  15. > How can I do this easily in C?
  16. >...
  17. > Perhaps I should loop through the string using strtok(), converting each
  18. > substring using atof()?
  19.  
  20. Something like that, yes.
  21.  
  22. > I'm sure it's straightforward, but I just can't see it (or find it in the FAQ).
  23.  
  24. There are some clues in there, which are expanded with an example
  25. or two in the book-length version:
  26.  
  27. 12.16:    How can I read data from data files with particular formats?
  28.     How can I read ten floats without having to use a jawbreaker
  29.     scanf format
  30.     like "%f %f %f %f %f %f %f %f %f %f"?
  31.     How can I read an arbitrary number of fields from a line into an
  32.     array?
  33.  
  34. A:    In general, there are three main ways of parsing data lines:
  35.  
  36.     ...
  37.  
  38.     2.    Break the line into fields separated by whitespace (or
  39.         some other delimiter), using strtok() or the equivalent
  40.         (see question 13.6), then deal with each field
  41.         individually, perhaps with routines like atoi() and
  42.         atof().  (Once the line is broken up, the code for
  43.         handling the fields is much like the traditional code in
  44.         main() for handling the argv array; see question 20.3.) 
  45.         This method is particularly useful for reading an
  46.         arbitrary (i.e. not known in advance) number of fields
  47.         from a line into an array.
  48.  
  49.         Here is a simple example which copies a line of up to 10
  50.         floating-point numbers (separated by whitespace) into an
  51.         array:
  52.  
  53.             #define MAXARGS 10
  54.  
  55.             char *av[MAXARGS];
  56.             int ac, i;
  57.             double array[MAXARGS];
  58.  
  59.             ac = makeargv(line, av, MAXARGS);
  60.             for(i = 0; i < ac; i++)
  61.                 array[i] = atof(av[i]);
  62.  
  63.         (See question 13.6 for the definition of makeargv().)
  64.  
  65.     ...
  66.  
  67. 13.6:    How can I split up a string into whitespace-separated fields?
  68.     How can I duplicate the process by which main() is handed argc
  69.     and argv?
  70.  
  71. A:    The only Standard routine available for this kind of
  72.     "tokenizing" is strtok...
  73.  
  74.     As an alternative, here is a routine I use for building an argv
  75.     all at once:
  76.  
  77.         #include <ctype.h>
  78.  
  79.         int makeargv(char *string, char *argv[], int argvsize)
  80.         {
  81.             char *p = string;
  82.             int  i;
  83.             int argc = 0;
  84.  
  85.             for(i = 0; i < argvsize; i++) {
  86.             /* skip leading whitespace */
  87.             while(isspace(*p))
  88.                 p++;
  89.  
  90.             if(*p != '\0')
  91.                 argv[argc++] = p;
  92.             else {
  93.                 argv[argc] = 0;
  94.                 break;
  95.             }
  96.  
  97.             /* scan over arg */
  98.             while(*p != '\0' && !isspace(*p))
  99.                 p++;
  100.             /* terminate arg: */
  101.             if(*p != '\0' && i < argvsize-1)
  102.                 *p++ = '\0';
  103.             }
  104.  
  105.             return argc;
  106.         }
  107.  
  108.     Calling makeargv() is straightforward:
  109.  
  110.         char *av[10];
  111.         int i, ac = makeargv(string, av, 10);
  112.         for(i = 0; i < ac; i++)
  113.             printf("\"%s\"\n", av[i]);
  114.  
  115.     [A call to makeargv will] modify the input string,
  116.     by inserting \0's to terminate each field.  If you'll need the
  117.     original string later, make a copy before breaking it up.
  118.  
  119.                         Steve Summit
  120.                         scs@eskimo.com
  121.